package com.tianyu.inspection.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.tianyu.inspection.entity.*;
import com.tianyu.inspection.mapper.*;
import com.tianyu.inspection.service.api.IStatisticsService;
import com.tianyu.inspection.entity.*;
import com.tianyu.inspection.mapper.*;
import org.springframework.stereotype.Service;
import org.springframework.ui.ModelMap;

import javax.annotation.Resource;
import java.util.*;

/**********************************
 * @Author YSW
 * @Description 数据统计
 * @Date 2021/3/1 - 10:39
 **********************************/

@Service
public class StatisticsServiceImpl implements IStatisticsService {

    @Resource
    private StatisticsMapper statisticsMapper;

    @Resource
    private ProjectMapper projectMapper;

    @Resource
    private UserMapper userMapper;

    @Resource
    private PipelineMapper pipelineMapper;

    @Resource
    private FlyTaskMapper flyTaskMapper;

    @Resource
    private DangerMapper dangerMapper;

    @Resource
    private UploadFileMapper uploadFileMapper;

    @Resource
    private ConstructionUnitsMapper constructionUnitsMapper;

    @Resource
    private ConstructionTypeMapper constructionTypeMapper;

    @Resource
    private HighConsequenceAreasMapper highConsequenceAreasMapper;

    @Resource
    private HighConsequenceAreasTypeMapper highConsequenceAreasTypeMapper;

    @Resource
    private PileCardMapper pileCardMapper;

    @Resource
    private PileCardTypeMapper pileCardTypeMapper;

    @Resource
    private GeneralFacilitiesMapper generalFacilitiesMapper;

    @Resource
    private GeneralFacilitiesTypeMapper generalFacilitiesTypeMapper;

    @Resource
    private CameraMapper cameraMapper;

    @Resource
    private CameraTypeMapper cameraTypeMapper;

    /**
     * 项目概要统计：
     * 各项目用户总量
     * 各项目管线总量
     * 各项目任务总量
     * 各项目险情总量
     * 各项目文件总量
     * 各项目基础设施总量
     *
     * @return Result
     */
    @Override
    public ModelMap projectSummaryStatistics() {
        List<Map<String, Object>> mapList = userStatistics();
        List<Map<String, Object>> mapList1 = pipelineStatistics();
        List<Map<String, Object>> mapList2 = flyTaskStatistics();
        List<Map<String, Object>> mapList3 = dangerStatistics();
        List<Map<String, Object>> mapList4 = fileStatistics();
        ModelMap modelMap5 = infrastructureStatistics();
        return new ModelMap()
                .addAttribute("user",mapList)
                .addAttribute("pipeline",mapList1)
                .addAttribute("flyTask",mapList2)
                .addAttribute("danger",mapList3)
                .addAttribute("file",mapList4)
                .addAttribute("infrastructure",modelMap5);
    }

    /**
     * 用户统计
     *
     * @return Result
     */
    @Override
    public List<Map<String, Object>> userStatistics() {
        List<Map<String, Object>> mapList1 = userMapper.selectMaps(new QueryWrapper<User>()
                .select("project_id as projectId,COUNT(*) as count").groupBy("project_id"));
        List<Map<String, Object>> mapList2 = userMapper.selectMaps(new QueryWrapper<User>()
                .select("project_id as projectId,role_id as roleId,COUNT(*) as count").groupBy("project_id,role_id"));
        setDimension(mapList1, mapList2,"dimension[role]");
        return mapList1;
    }

    private void setDimension(List<Map<String, Object>> mapList1, List<Map<String, Object>> mapList2,String dimensionName) {
        HashMap<String, List<Map<String, Object>>> modelMap = new HashMap<>(10);
        mapList2.forEach(map2 -> {
            String projectId = map2.get("projectId").toString();
            if (!modelMap.containsKey(projectId)){
                modelMap.put(projectId,new ArrayList<>());
            }
            map2.remove("projectId");
            modelMap.get(projectId).add(map2);
        });
        mapList1.forEach(map1 -> {
            String projectId = map1.get("projectId").toString();
            if (Objects.nonNull(projectId)){
                map1.put(dimensionName,modelMap.get(map1.get("projectId").toString()));
            }else {
                map1.put(dimensionName,null);
            }
        });
    }

    /**
     * 文件统计
     *
     * @return Result
     */
    @Override
    public List<Map<String, Object>> fileStatistics() {
        List<Map<String, Object>> mapList1 = uploadFileMapper.selectMaps(new QueryWrapper<UploadFile>()
                .select("project_id as projectId,COUNT(*) as count").groupBy("project_id"));
        List<Map<String, Object>> mapList2 = uploadFileMapper.selectMaps(new QueryWrapper<UploadFile>()
                .select("project_id as projectId,category,COUNT(*) as count").groupBy("project_id,category"));
        setDimension(mapList1, mapList2,"dimension[category]");
        return mapList1;
    }

    /**
     * 管线统计
     *
     * @return Result
     */
    @Override
    public List<Map<String, Object>> pipelineStatistics() {
        return pipelineMapper.selectMaps(new QueryWrapper<Pipeline>()
                .select("project_id as projectId,COUNT(*) as count").eq("state",0).groupBy("project_id"));
    }

    /**
     * 飞行历史统计
     *
     * @return Result
     */
    @Override
    public List<Map<String, Object>> flyTaskStatistics() {
        return flyTaskMapper.selectMaps(new QueryWrapper<FlyTask>()
                .select("project_id as projectId,COUNT(*) as count").eq("state",0).groupBy("project_id"));
    }

    /**
     * 险情统计
     *
     * @return Result
     */
    @Override
    public List<Map<String, Object>> dangerStatistics() {
        List<Map<String, Object>> mapList1 = dangerMapper.selectMaps(new QueryWrapper<Danger>()
                .select("project_id as projectId,COUNT(*) as count").eq("state",0).groupBy("project_id"));
        List<Map<String, Object>> mapList2 = dangerMapper.selectMaps(new QueryWrapper<Danger>()
                .select("project_id as projectId,danger_type_id as dangerTypeId ,COUNT(*) as count").eq("state",0).groupBy("project_id,danger_type_id"));
        List<Map<String, Object>> mapList3 = dangerMapper.selectMaps(new QueryWrapper<Danger>()
                .select("project_id as projectId,status,COUNT(*) as count").eq("state",0).groupBy("project_id,status"));
        setDimension(mapList1, mapList2,"dimension[dangerType]");
        setDimension(mapList1, mapList3,"dimension[status]");
        return mapList1;
    }

    /**
     * 基础设施统计
     *
     * @return Result
     */
    @Override
    public ModelMap infrastructureStatistics() {
        List<Map<String, Object>> mapList = highConsequenceAreasMapper.selectMaps(new QueryWrapper<HighConsequenceAreas>()
                .select("project_id as projectId,COUNT(*) as count").groupBy("project_id")
                .eq("state",0));
        List<Map<String, Object>> mapList01 = highConsequenceAreasMapper.selectMaps(new QueryWrapper<HighConsequenceAreas>()
                .select("project_id as projectId,high_consequence_areas_type_id as highConsequenceAreasTypeId,COUNT(*) as count")
                .eq("state",0)
                .groupBy("project_id,high_consequence_areas_type_id"));
        setDimension(mapList, mapList01,"dimension[highConsequenceAreasType]");

        List<Map<String, Object>> mapList1 = constructionUnitsMapper.selectMaps(new QueryWrapper<ConstructionUnits>()
                .select("project_id as projectId,COUNT(*) as count").groupBy("project_id")
                .eq("state",0));
        List<Map<String, Object>> mapList11 = constructionUnitsMapper.selectMaps(new QueryWrapper<ConstructionUnits>()
                .select("project_id as projectId,construction_type_id as constructionTypeId,COUNT(*) as count")
                .eq("state",0)
                .groupBy("project_id,construction_type_id"));
        setDimension(mapList1, mapList11,"dimension[constructionType]");

        List<Map<String, Object>> mapList2 = pileCardMapper.selectMaps(new QueryWrapper<PileCard>()
                .select("project_id as projectId,COUNT(*) as count")
                .eq("state",0).groupBy("project_id"));
        List<Map<String, Object>> mapList21 = pileCardMapper.selectMaps(new QueryWrapper<PileCard>()
                .select("project_id as projectId,pile_card_type_id as pileCardType,COUNT(*) as count")
                .eq("state",0)
                .groupBy("project_id,pile_card_type_id"));
        setDimension(mapList2, mapList21,"dimension[pileCardType]");

        List<Map<String, Object>> mapList3 = generalFacilitiesMapper.selectMaps(new QueryWrapper<GeneralFacilities>()
                .select("project_id as projectId,COUNT(*) as count")
                .eq("state",0).groupBy("project_id"));
        List<Map<String, Object>> mapList31 = generalFacilitiesMapper.selectMaps(new QueryWrapper<GeneralFacilities>()
                .select("project_id as projectId,general_facilities_type_id as generalFacilitiesType,COUNT(*) as count")
                .eq("state",0)
                .groupBy("project_id,general_facilities_type_id"));
        setDimension(mapList3, mapList31,"dimension[generalFacilitiesType]");

        List<Map<String, Object>> mapList4 = cameraMapper.selectMaps(new QueryWrapper<Camera>()
                .select("project_id as projectId,COUNT(*) as count")
                .eq("state",0).groupBy("project_id"));
        List<Map<String, Object>> mapList41 = cameraMapper.selectMaps(new QueryWrapper<Camera>()
                .select("project_id as projectId,camera_type_id as cameraTypeId,COUNT(*) as count")
                .eq("state",0)
                .groupBy("project_id,camera_type_id"));
        setDimension(mapList4, mapList41,"dimension[cameraTypeId]");


        return new ModelMap().addAttribute("highConsequenceAreas",mapList)
                .addAttribute("constructionUnits",mapList1)
                .addAttribute("pileCard",mapList2)
                .addAttribute("generalFacilities",mapList3)
                .addAttribute("camera",mapList4);
    }

    /**
     * 基础设施类型统计
     *
     * @return Result
     */
    @Override
    public ModelMap infrastructureTypeStatistics() {
        Integer count1 = Math.toIntExact(highConsequenceAreasTypeMapper.selectCount(new QueryWrapper<HighConsequenceAreasType>().eq("state",0)));
        Integer count2 = Math.toIntExact(constructionTypeMapper.selectCount(new QueryWrapper<ConstructionType>().eq("state",0)));
        Integer count3 = Math.toIntExact(pileCardTypeMapper.selectCount(new QueryWrapper<PileCardType>().eq("state",0)));
        Integer count4 = Math.toIntExact(generalFacilitiesTypeMapper.selectCount(new QueryWrapper<GeneralFacilitiesType>().eq("state",0)));
        Integer count5 = Math.toIntExact(cameraTypeMapper.selectCount(new QueryWrapper<CameraType>().eq("state",0)));
        return new ModelMap().addAttribute("highConsequenceAreasType",count1)
                .addAttribute("constructionType",count2)
                .addAttribute("pileCardType",count3)
                .addAttribute("generalFacilitiesType",count4)
                .addAttribute("cameraType",count5);
    }
}
